package main

import (
	"fmt"
)

func test(fn func() int) int {
	return fn()
}

// 命名返回参数可看做与形参类似的局部变量，最后由 return 隐式返回。
func add(x, y int) (z int) {
	z = x + y
	return
}

type FormatFunc func(s string, x, y int) string // 定义函数类型。
func format(fn FormatFunc, s string, x, y int) string {

	return fn(s, x, y)
}

// 命名返回参数允许 defer 延迟调⽤用通过闭包读取和修改。
func add2(x, y int) (z int) {
	defer func() {
		z += 100
	}()
	z = x + y
	return
}

// 显式 return 返回前，会先修改命名返回参数。
func add3(x, y int) (z int) {
	defer func() {
		println(z) // 输出: 203
	}()
	z = x + y
	return z + 200 // 执⾏行顺序: (z = z + 200) -> (call defer) -> (ret)
}
func main() {
	s1 := test(func() int { return 100 }) // 直接将匿名函数当参数。
	s2 := format(func(s string, x, y int) string {
		return fmt.Sprintf(s, x, y)
	}, "%d, %d", 10, 20)
	println(s1, s2)

	println(add(1, 2))

	println(add2(1, 2)) // 输出: 103

	println(add3(1, 2)) // 输出: 203
}
